1 /* FOREGEJ - FOrmatting REfactoring GEnerating Java
2 *
3 * Copyright (C) 2003 Andreas Arrgard
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 package com.octagroup.foregej.antlr;
20 import antlr.ASTFactory;
21 import antlr.ASTPair;
22 import antlr.Token;
23 import antlr.collections.AST;
24 import antlr.collections.impl.ASTArray;
25 /***
26 */
27 public abstract class DynASTFactory extends ASTFactory
28 {
29 protected DynTypeFactory typeFactory_=null;
30 protected ASTPair lastASTPair_=null;
31 /***
32 * Constructor creates a new DynASTFactory object.
33 */
34 protectedDynASTFactory(Class types,String[] packages)/package-summary.html"> DynASTFactory(Class types,String[] packages)
35 {
36 typeFactory_=new DynTypeFactory("AST_", types, packages,
37 getDefaultASTType());
38 }
39 /***
40 * Constructor creates a new DynASTFactory object.
41 * <p>
42 * This method uses the type factory from the template to speed up
43 * construction.
44 * </p>
45 */
46 protected DynASTFactory(DynASTFactory template)
47 {
48 typeFactory_=template.typeFactory_;
49 }
50 /***
51 * DOCUMENT ME!
52 *
53 * @param type DOCUMENT ME!
54 * @return DOCUMENT ME!
55 * @throws RuntimeException DOCUMENT ME!
56 */
57 public Class getASTNodeType(int type)
58 {
59 Class astClass=typeFactory_.getClass4Type(type);
60 return astClass;
61 }
62 /***
63 * DOCUMENT ME!
64 *
65 * @param currentAST DOCUMENT ME!
66 * @param child DOCUMENT ME!
67 */
68 public void addASTChild(ASTPair currentAST,AST child)
69 {
70 //
71 // make sure that the instances are of correct type
72 //
73 lastASTPair_=currentAST;
74 super.addASTChild(currentAST, child);
75 }
76 /***
77 * DOCUMENT ME!
78 *
79 * @param currentAST DOCUMENT ME!
80 * @param root DOCUMENT ME!
81 */
82 public void makeASTRoot(ASTPair currentAST,AST root)
83 {
84 //
85 // make sure that the child instances are of correct type
86 //
87 lastASTPair_=currentAST;
88 super.makeASTRoot(currentAST, root);
89 }
90 /***
91 * Must override this method to make user that all the asts in an
92 * array are of the correct type.
93 *
94 * @param arr the array to check
95 * @return The new root
96 */
97 public AST make(ASTArray arr)
98 {
99 for(int i=arr.size-1; i>=0; i--){
100 arr.array[i]=checkAST(arr.array[i]);
101 }
102 return super.make(arr);
103 }
104 /***
105 * DOCUMENT ME!
106 *
107 * @param ast DOCUMENT ME!
108 * @return DOCUMENT ME!
109 * @throws RuntimeException DOCUMENT ME!
110 */
111 private AST checkAST(AST ast)
112 {
113 if(ast==null) {
114 return null;
115 }
116 try{
117 Class factoryClass=getASTNodeType(ast.getType());
118 Class childClass=ast.getClass();
119 if(factoryClass!=childClass) {
120 AST newAST=(AST)factoryClass.newInstance();
121 newAST.initialize(ast);
122 AST firstChild=ast.getFirstChild();
123 AST nextSibling=ast.getNextSibling();
124 ast.setFirstChild(null);
125 ast.setNextSibling(null);
126 newAST.setFirstChild(firstChild);
127 newAST.setNextSibling(nextSibling);
128 // make it official
129 ast=newAST;
130 }
131 return ast;
132 }catch (InstantiationException e) {
133 e.printStackTrace();
134 throw new RuntimeException("Failed to instantiate AST node:InstantiationException:"+e.getMessage());
135 }catch (IllegalAccessException e) {
136 throw new RuntimeException("Failed to instantiate AST node:IllegalAccessException:"+e.getMessage());
137 }
138 }
139 /***
140 * As ASTs are created from tokens we need to signal that an ast
141 * actually has been created for that token.
142 *
143 * @param token
144 * @return
145 */
146 public AST create(Token token)
147 {
148 BaseAST ast=(BaseAST)super.create(token);
149 ast.setASTFactory(this);
150 ((BaseToken)token).setCreatedAst(ast);
151 return ast;
152 }
153 /***
154 * @return
155 */
156 protected abstract Class getDefaultASTType();
157
158 /***
159 * Signals that an AST has altered its type.
160 * <p>
161 * This metod is invoked from the <code>BaseAST</code>
162 * </p>
163 *
164 * @param oldAST the altered ast.
165 */
166 public void typeAltered(BaseAST oldAST)
167 {
168 // the last ast pair should contain the altered ast!
169 //
170 // check root!
171 //
172 if(lastASTPair_.root==oldAST) {
173 lastASTPair_.root=checkAST(lastASTPair_.root);
174 return;
175 }
176 //
177 // check first child
178 //
179 if(lastASTPair_.root.getFirstChild()==oldAST) {
180 lastASTPair_.root.setFirstChild(checkAST(lastASTPair_.root.getFirstChild()));
181 return;
182 }
183 //
184 // check all the siblings
185 //
186 AST node=lastASTPair_.root.getFirstChild();
187 while(node.getNextSibling()!=null){
188 if(node.getNextSibling()==oldAST) {
189 node.setNextSibling(checkAST(node.getNextSibling()));
190 return;
191 }
192 node=node.getNextSibling();
193 }
194 throw new IllegalStateException("Failed to update altered ast");
195 }
196 }
This page was automatically generated by Maven